<script lang="ts">
import { createVNode, resolveComponent, defineComponent, PropType, VNode, computed, reactive } from 'vue'
import { inputTypes, modelValueTypes } from "@/components/elementDif";
import DifInput from "../elementDif/index.vue"

export default defineComponent({
  name: 'formItem',
  props: {
    // el-form-item的label
    label: {
      type: String,
    },
    // 输入框类型,支持的输入框见 inputTypes
    type: {
      type: String,
      required: true,
      validator: (value: string) => {
        return inputTypes.includes(value)
      },
    },
    // 双向绑定值
    modelValue: {
      required: true,
    },
    // 输入框的附加属性
    inputAttr: {
      type: Object as PropType<InputAttr>,
      default: () => { },
    },
    // el-form-item的附加属性
    attr: {
      type: Object as PropType<FormItemAttr>,
      default: () => { },
    },
    // 额外数据,radio、checkbox的选项等数据
    data: {
      type: Object as PropType<InputData>,
      default: () => { },
    },
    prop: {
      type: String,
      default: '',
    },
    placeholder: {
      type: String,
      default: '',
    },
  },
  emits: ['update:modelValue'], //常规写法中在子组件自定义事件,如果与v-model绑定 就要用update:modelValue或者update:name name根据父组件(v-model:name="data")
  setup(props, { emit }) {
    //setup(props, { emit }) 也可以 setup(props, context){context.emit('update:modelValue', value)}
    const onValueUpdate = (value: modelValueTypes) => {
      emit('update:modelValue', value)
    }

    const blockHelp = computed(() => {
      return props.attr && props.attr['block-help'] ? props.attr['block-help'] : ''
    })

    // el-form-item 的默认插槽,生成一个baInput
    const defaultSlot = () => {
      let inputNode = createVNode(DifInput, {
        type: props.type,
        attr: { placeholder: props.placeholder, ...props.inputAttr },
        data: props.data,
        modelValue: props.modelValue,
        'onUpdate:modelValue': onValueUpdate,
      })
      return inputNode
    }

    let noNeedLabelSlot = [
      'string',
      'password',
      'number',
      'textarea',
      'datetime',
      'year',
      'date',
      'time',
      'select',
      'selects',
      'remoteSelect',
      'city',
      'icon',
    ] // 不带独立label输入框
    let needLabelSlot = ['radio', 'checkbox', 'switch', 'array', 'image', 'images', 'file', 'files', 'editor'] // 需要独立label的输入框
    if (noNeedLabelSlot.includes(props.type)) {
      return () =>
        createVNode(
          resolveComponent('el-form-item'),
          {
            prop: props.prop,
            ...props.attr,
            label: props.label,
          },
          {
            default: defaultSlot,
          }
        )
    } else if (needLabelSlot.includes(props.type)) {
      // 带独立label的输入框
      let title = props.data && props.data.title ? props.data.title : props.label
      const labelSlot = () => {
        return [
          createVNode(
            'div',
            {
              class: 'ba-form-item-label',
            },
            [
              createVNode('div', null, title),
              createVNode(
                'div',
                {
                  class: 'ba-form-item-label-tip',
                },
                props.data && props.data.tip ? props.data.tip : ''
              ),
            ]
          ),
        ]
      }

      return () =>
        createVNode(
          resolveComponent('el-form-item'),
          {
            class: 'ba-input-item-' + props.type,
            prop: props.prop,
            ...props.attr,
            label: props.label,
          },
          {
            label: labelSlot,
            default: defaultSlot,
          }
        )
    }
  },
})
</script>
<style scoped lang="scss">
.ba-form-item-label {
  display: inline-block;

  .ba-form-item-label-tip {
    padding-left: 6px;
    font-size: 12px;
    color: var(--el-text-color-secondary);
  }
}

.ba-form-item-not-support {
  line-height: 15px;
}

.ba-input-item-array :deep(.el-form-item__content) {
  display: block;
  padding-bottom: 32px;
}
</style> 